﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UFSoft.UBF.Business;
using UFSoft.UBF.Eventing;
using UFIDA.U9.SM.Ship;
using UFIDA.U9.PM.PO;
using UFSoft.UBF.PL;
using UFIDA.U9.PM.Rcv;
using UFIDA.U9.SM.RMA;
using UFIDA.U9.SM.SO;
using UFIDA.U9.CBO.SCM.Customer;
using UFIDA.U9.PR.PurchaseRequest;
using UFSoft.UBF.Util.DataAccess;
using UFIDA.U9.CBO.SCM.Item;
using UFIDA.U9.PM.PC;
using UFSoft.UBF.PL.Engine;
using System.Data;
using UFIDA.U9.Base.Profile;
using UFIDA.U9.Base;
using System.Reflection.Emit;
using UFIDA.U9.MO.WF;
using System.Runtime.Caching;
using UFSoft.UBF.PL.ObjectAccess;
using UFIDA.U9.MO.Enums;


namespace UFIDA.U9.Cust.LS.PlugBE
{
    /// <summary>
    /// 爱发科
    /// 请购单
    /// 
    /// 提交时,清空同步标志
    /// 
    /// 1.1请购单现存量查询:
    /// 1.需求人员在U9C系统录入请购单，系统根据料号+指定指番+指定仓库（参数设置，待确认）
    /// 显示可供应数量（指定仓库+指番+公共指番可用量+对应料品+对应指番+公共指番的在途），
    /// 点击保存按钮触发计算逻辑。
    /// </summary>
    class AFKPRExtend_bak : IEventSubscriber
    {
        //配置XX.sub.xml文件放置到portal/bin下，dll文件放置到portal/ApplicationServer/Libs下
        public void Notify(params object[] args)
        {
            if (args != null && args.Length != 0 && args[0] is EntityEvent)
            {
                BusinessEntity.EntityKey key = ((EntityEvent)args[0]).EntityKey;
                UFIDA.U9.PR.PurchaseRequest.PR be = key.GetEntity() as UFIDA.U9.PR.PurchaseRequest.PR;
                if (be == null)
                    return;

                if (be.SysState == ObjectState.Inserted)
                {
                    //新增/复制
                    //初始版本
                    be.DescFlexField.PrivateDescSeg6 = "";
                }

                if (be.Status == PRStatusEnum.OpenOpen)
                {
                  
                    if (be.DocType.Code == "PR1" || be.DocType.Code == "PR3")
                    {
                        
                        //保存
                        //库存查询+数量更新
                        QohQuery(be);
                    }
                    else
                    {
                        foreach (var line in be.PRLineList)
                        {
                            if (string.IsNullOrEmpty(line.DescFlexSegments.PrivateDescSeg9)) throw new Exception("需求数量(手工)为空");
                            decimal sl = decimal.Parse(line.DescFlexSegments.PrivateDescSeg9);//需求数量(手工)

                             line.ReqQtyReqUOM = sl;//需求数量1
                            line.ApprovedQtyReqUOM = sl;//核准数量1
                            line.ReqQtyTU = sl;// 需求数量1采购单位
                            line.ReqQtyPU = sl;// 需求数量1 
                            line.ApprovedQtyTU = sl;// 需求数量1采购单位
                            line.ApprovedQtyPU = sl;// 需求数量1
                        }

                    }
                    
                }
                else if ((be.Status == PRStatusEnum.Approving && be.OriginalData.Status == PRStatusEnum.OpenOpen))
                {
                    // 提交时
                    // 清空同步标志
                    UpdateSyncFlag(be);
                    //版本+1
                    AddVersion(be);
                }
                if (be.Status == PRStatusEnum.Approved && be.OriginalData.Status == PRStatusEnum.Approving)
                {

                    //请购审核时,单据类型是PR1或者PR3的时候(专用件请购,工序委外请购)

                    if (be.DocType.Code == "PR1" || be.DocType.Code == "PR3")
                    {
                        //如果生产订单已经完工,则把单据改为开立状态
                        foreach (var line in be.PRLineList)
                        {
                            if (!string.IsNullOrEmpty(line.DescFlexSegments.PrivateDescSeg2)) { 
                            UFIDA.U9.MO.MO.MO mo = UFIDA.U9.MO.MO.MO.Finder.Find("DocNo='" + line.DescFlexSegments.PrivateDescSeg2 + "'");
                            if (mo != null) { 
                            if (mo.DocState == MOStateEnum.Complete  )
                            {
                                MOUnApprove(be);
                            }
                            }
                            else
                            {

                                throw new Exception("生产订单查询异常");
                            }
                            }
                        }
                    }
                }

            }

        }

        /// <summary>
        /// 请购审核时,如果生产订单已经完工,则把单据改为开立状态
        /// </summary>
        /// <param name="be"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void MOUnApprove(PR.PurchaseRequest.PR Doc)
        {
           foreach(var line in Doc.PRLineList)
            {

                UFIDA.U9.MO.MO.MO mO = UFIDA.U9.MO.MO.MO.Finder.Find("DocNo='" + line.DescFlexSegments.PrivateDescSeg2 +"'");
                if (mO != null)
                {
                     
                    DateTime dateTime = DateTime.Now;
                    if (dateTime > mO.ActualCompleteDate.ToUniversalTime()&& 
                        dateTime.Year!=mO.ActualCompleteDate.Year||dateTime.Month!=mO.ActualCompleteDate.Month)
                    {
                        Doc.Status = PRStatusEnum.OpenOpen;
                        throw new Exception($"请购单[{Doc.DocNo}]审核日期大于[{mO.DocNo}]生产订单完工日期,并且已跨月");
                    }
                }
                

            }

         }

        /// <summary>
        /// 请购单库存查询
        /// 更新 需求数量(标准)
        /// </summary>
        /// <param name="be"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void QohQuery(PR.PurchaseRequest.PR doc)
        {
            Dictionary<String, decimal> map = new Dictionary<string, decimal>();

            foreach (var line in doc.PRLineList)
            {
                long itemid = line.ItemInfo.ItemID.ID;//料品
                string projcode = line.Project?.Code;//项目

                string projcodes = GetParam("AFKPRQOHPROJ",Context.LoginOrg.Code);//公共项目 通过参数获取
                string whcodes = GetParam("AFKPRQOHCK", Context.LoginOrg.Code);//仓库 通过参数获取
                if (string.IsNullOrEmpty(line.DescFlexSegments.PrivateDescSeg9)) throw new Exception("需求数量(手工)为空");
                decimal sgsl = decimal.Parse(line.DescFlexSegments.PrivateDescSeg9);//需求数量(手工)


                if (string.IsNullOrEmpty(projcodes) && string.IsNullOrEmpty(whcodes))
                {
                    // 没填参数设置 把手工数量赋值给标准字段
                    line.ReqQtyReqUOM = sgsl;//需求数量1
                    line.ApprovedQtyReqUOM = sgsl;//核准数量1
                    line.ReqQtyTU = sgsl;// 需求数量1采购单位
                    line.ReqQtyPU = sgsl;// 需求数量1 
                    line.ApprovedQtyTU = sgsl;// 需求数量1采购单位
                    line.ApprovedQtyPU = sgsl;// 需求数量1
                }
                else
                {
                    //填写了参数
                    if (projcodes.Length > 1 && projcodes[0] == '"' && projcodes[projcodes.Length - 1] == '"')
                    {
                        projcodes = projcodes.Trim('"');
                    }

                    string[] projcodelist = projcodes.Split(',');
                    string projcodepath = string.Join("','", projcodelist);


                    // 去除两端的双引号
                    if (whcodes.Length > 1 && whcodes[0] == '"' && whcodes[whcodes.Length - 1] == '"')
                    {
                        whcodes = whcodes.Trim('"');
                    }
                    string[] whcodelist = whcodes.Split(',');
                    string whcodepath = string.Join("','", whcodelist);
                    String wh;
                    String proj;
                    if (whcodelist.Length > 0 && !string.Join("", whcodelist).Equals(""))
                    {
                        wh = $"and wh.Code in ('{whcodepath}')";
                    }
                    else
                    {
                        wh = "";
                    }
                    if (projcodepath.Length > 0 && !string.Join("", projcodepath).Equals(""))
                    {
                        proj = $"and proj.Code in ('{projcodepath}')";
                    }
                    else
                    {
                        proj = "";
                    }

                    decimal kyl = 0; //可用量

                    //查询缓存
                    string key = Context.LoginOrg.ID + "-" + wh + "-" + proj + "-" + itemid;
                    if (map.ContainsKey(key))
                    {
                        //缓存中存在
                        kyl = map[key];
                    }
                    else
                    {
                        kyl = GetKyl(itemid, wh, proj);
                    }
                    //可用量赋值
                    line.DescFlexSegments.PrivateDescSeg10 = kyl.ToString();

                     ItemMaster item = ItemMaster.Finder.Find("id='" + line.ItemInfo.ItemID + "'");
                      decimal minqty= item.PurchaseInfo.MinRcvQty;

                    // 更新需求数量
                    decimal xqsl = sgsl - kyl;//需求差异
                        //
                        if (xqsl > 0)
                        {

                            //需求>供给
                            line.DescFlexSegments.PrivateDescSeg8 = "False";//是否消库
                            line.ReqQtyReqUOM = xqsl;//需求数量1
                            line.ApprovedQtyReqUOM = xqsl;//核准数量1
                            line.ReqQtyTU = xqsl;// 需求数量1采购单位
                            line.ReqQtyPU = xqsl;// 需求数量1 
                            line.ApprovedQtyTU = xqsl;// 需求数量1采购单位
                            line.ApprovedQtyPU = xqsl;// 需求数量1
                            kyl = 0;//可用量
                        }
                        else
                        {
                            //需求<=供给

                            //需求>供给
                            line.DescFlexSegments.PrivateDescSeg8 = "true";//是否消库
                            line.ReqQtyReqUOM = sgsl;//需求数量1
                            line.ApprovedQtyReqUOM = sgsl;//核准数量1
                            line.ReqQtyTU = sgsl;// 需求数量1采购单位
                            line.ReqQtyPU = sgsl;// 需求数量1 
                            line.ApprovedQtyTU = sgsl;// 需求数量1采购单位
                            line.ApprovedQtyPU = sgsl;// 需求数量1
                            kyl -= sgsl;//剩余可用量=可用量-需求数量
                        }
                      
                     

                    //更新缓存可用量
                    if (map.ContainsKey(key))
                    {
                        map[key] = kyl;
                    }
                    else
                    {
                        map.Add(key, kyl);
                    }
                }

                
            }
        }

        private static decimal GetKyl(long itemid, string wh, string proj)
        {
            object kyl;
            //查询数据库
            string sql = $@"  
                        select
                        -- cmxsj.Project,
                        sum(mxsj.sl-inv.SafetyStockQty)sl
                        from (select
                        *
                        from (
                        SELECT 
                        qoh.ItemInfo_ItemID 
                        ,qoh.project
                        ,sum(qoh.StoreQty)sl
                        FROM
                        InvTrans_WhQoh qoh
                        left join CBO_ItemMaster item on item.ID=qoh.ItemInfo_ItemID
                        left join CBO_InventoryInfo inv on inv.ID=item.InventoryInfo
                        left join CBO_Wh wh on wh.ID=qoh.Wh
                        -- JOIN  CBO_Project proj on  proj.id=qoh.project

                         WHERE  1 = 1
                        -- and wh.Code in ('','') -- 仓库拼接
                         {wh} 
                        AND qoh.ItemInfo_ItemID= '{itemid}' 
                          AND qoh.StoreQty!=0
                         and qoh.LogisticOrg={Context.LoginOrg.ID}
                        group	by qoh.ItemInfo_ItemID ,qoh.project,wh.Code 
                        ) kc
                        union all
                        -- 请购在途
                        select * from  (  
                        SELECT 
                        prline.ItemInfo_ItemID
                        ,prline.project,
                        sum(prline.ApprovedQtyTU - prline.TotalToPOQtyTU) sl -- 	请购在途=请购已核准数量-已转采购数量
                        FROM
                        PR_PR pr
                        JOIN PR_PRLine prline ON prline.PR= pr.ID
                        JOIN PR_PRDocType ty ON ty.id= pr.PRDocType
                        JOIN   CBO_Project proj on  proj.id=prline.project
                        WHERE
                        prline.Status=2
                        and ty.Code !='PR99' 
                        and prline.DescFlexSegments_PrivateDescSeg8 = 'False'  -- 消库不取
                        and pr.Org={Context.LoginOrg.ID}
                        {proj}
                         group by prline.ItemInfo_ItemID,prline.project
                        ) qgzt
                        union all
                        -- 采购在途
                        select * from  (
                        SELECT  
                        poline.ItemInfo_ItemID
                        ,ship.project,
                        sum(ship.PlanArriveQtyPU - ship.TotalRecievedQtyPU) sl --采购订单在途 = 采购订单核准数量-已收货数量-累计退扣数量
	 
                        FROM
                        PM_PurchaseOrder po
                        JOIN PM_POLine poline ON poline.PurchaseOrder= po.ID 
                        JOIN PM_POShipLine ship ON poline.id= ship.POLine
                        JOIN   CBO_Project proj on  proj.id=ship.project
                        JOIN PM_PODocType pty ON pty.id= po.DocumentType 
                       
                        WHERE 1=1 
                         {proj}
                        and poline.Status in(0,1,2,3)
                        and pty.code!='PO99' 
                        and po.Org={Context.LoginOrg.ID}
                         group by ship.project, poline.ItemInfo_ItemID
                        ) cgzt  
                        )mxsj

                          left join CBO_ItemMaster item on item.ID=mxsj.ItemInfo_ItemID
                        left join CBO_InventoryInfo inv on inv.ID=item.InventoryInfo

                        WHERE
                        1 = 1 
                          AND mxsj.ItemInfo_ItemID= '{itemid}' 

                        -- and wh.Code in ('16')
                      -- wh
                     --   proj 

                        group	 by  mxsj.ItemInfo_ItemID
                        ,mxsj.Project                      
                     ";
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null, out kyl);
            if (kyl == null)
            {
                return 0;
            }
            else
            {
                return decimal.Parse(kyl.ToString());
            }
            
        }

        /// <summary>
        /// 读取U9参数
        /// </summary>
        /// <param name="code"></param>
        /// <param name="orgcode"></param>
        /// <returns></returns>
        private static string GetParam(string code,string orgcode)
        {
            Profile profile = Profile.Finder.Find($"Code='{code}'");
            if (profile == null || profile.ProfileValues == null || profile.ProfileValues.Count == 0)
                return "";
            if (string.IsNullOrEmpty(orgcode))
            {
                return profile.ProfileValues[0].Value;
            }
            else
            {
                foreach (ProfileValue value in profile.ProfileValues)
                {
                    if (value.Organization.Code == orgcode)
                    {
                        return value.Value;
                    }
                }
            }
            throw new Exception($"获取参数[{code}]失败!");
        }

        /// <summary>
        /// 版本+1
        /// </summary>
        /// <param name="be"></param>
        private static void AddVersion(PR.PurchaseRequest.PR be)
        {
            if (string.IsNullOrEmpty(be.DescFlexField.PrivateDescSeg6))
            {
                //版本初始2
                be.DescFlexField.PrivateDescSeg6 = "1";
            }
            else
            {
                //版本+1
                int ver = Int32.Parse(be.DescFlexField.PrivateDescSeg6);
                be.DescFlexField.PrivateDescSeg6 = (ver + 1).ToString();
            }
        }
        /// <summary>
        /// 清除同步标志
        /// </summary>
        /// <param name="be"></param>
        private static void UpdateSyncFlag(PR.PurchaseRequest.PR be)
        {
            DateTime now = DateTime.Now;
            string formatted = now.ToString("yyyy-MM-dd HH:mm:ss");
            //String sql = $"Update pr_pr set DescFlexField_PrivateDescSeg3='',DescFlexField_PrivateDescSeg4='{formatted}' WHERE docno='{be.DocNo}'";
            //DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null);
            be.DescFlexField.PrivateDescSeg3 = "";
            be.DescFlexField.PrivateDescSeg4 = formatted;
        }
    }
}
